package mini.expr.lists;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;

import mini.Proc;
import mini.expr.Element;
import mini.expr.Expr;
import mini.memory.MemoryManager;


public class HeapCdr extends Expr {
    private Expr e;
    
    public HeapCdr(Expr e) {
        this.e = e;
    }

    public Element eval(HashMap<String, Element> nametable, HashMap<String, Proc> functiontable, LinkedList var) {
        Element list = e.eval(nametable, functiontable, var);
        
        if (!list.isList()) {
            throw new IllegalStateException("Expression does not evaluate to a list.");
        }
        
        int numElements = list.getListValue().getSequence().numElements();
        
        if (numElements == 0) {
            throw new IllegalStateException("List contains no elements. Cannot do cdr.");
        }
        
        Element element = new Element(new ElementList());
        
        element.getListValue().getSequence().setUsesHeap(true);
        
        if (numElements == 1) {
            return element;
        }
        
        Integer memoryAddress = list.getListValue().getSequence().getMemoryAddress();
        Integer elementAddressAtIndex = MemoryManager.getInstance().getElementAddressAtIndex(memoryAddress, 1);
        
        element.getListValue().getSequence().setMemoryAddress(elementAddressAtIndex);
        
        return element;
    }
}
